import 'dart:async';
import 'dart:typed_data';

import 'package:flame/components.dart';
import 'dart:ui' as ui;

import 'package:flame/flame.dart';

class MaskedImageComponent extends PositionComponent {
  final String maskImagePath; // 黑白遮罩
  final String colorImagePath; // 彩色图
  late ui.Image _maskImage; // 黑白图
  late ui.Image _colorImage; // 彩色图
  bool _isLoaded = false;
  late double setWidth; // 给定宽度
  late double pixelOffset;

  MaskedImageComponent({
    required this.maskImagePath,
    required this.colorImagePath,
    required this.setWidth,
    this.pixelOffset = 0,
    super.position,
  });

  @override
  Future<void> onLoad() async {
    _maskImage = await Flame.images.load(maskImagePath);
    _colorImage = await Flame.images.load(colorImagePath);
    scaleImage(_colorImage);
    final byteData = await _maskImage.toByteData(
      format: ui.ImageByteFormat.rawRgba,
    );
    final Uint8List maskPixels = byteData!.buffer.asUint8List();

    // 【rgba】
    for (int i = 0; i < maskPixels.lengthInBytes; i += 4) {
      final r = maskPixels[i];
      final g = maskPixels[i + 1];
      final b = maskPixels[i + 2];

      final brightness = (r + g + b) ~/ 3;
      maskPixels[i + 3] = brightness.clamp(0, 255); // 黑白图 -> 透明图 -> 合成（遮罩）
    }

    final completer = Completer<ui.Image>();
    ui.decodeImageFromPixels(
      maskPixels,
      _maskImage.width,
      _maskImage.height,
      ui.PixelFormat.rgba8888,
      completer.complete,
    );
    _maskImage = await completer.future;

    _isLoaded = true;
  }

  @override
  void render(ui.Canvas canvas) {
    // 合成图片
    if (!_isLoaded) return;
    final paint = ui.Paint();
    canvas.saveLayer(null, paint);
    canvas.drawImageRect(
      _colorImage,
      ui.Rect.fromLTWH(
        pixelOffset,
        pixelOffset,
        _colorImage.width.toDouble(),
        _colorImage.height.toDouble(),
      ),
      ui.Rect.fromLTWH(0, 0, size.x, size.y),
      paint,
    );
    paint.blendMode = ui.BlendMode.dstIn;
    canvas.drawImageRect(
      _maskImage,
      ui.Rect.fromLTWH(
        0,
        0,
        _maskImage.width.toDouble(),
        _maskImage.height.toDouble(),
      ),
      ui.Rect.fromLTWH(0, 0, size.x, size.y),
      paint,
    );
    canvas.restore();
  }

  // 放缩图片
  void scaleImage(ui.Image colorImage) {
    double radio = colorImage.width / colorImage.height;
    size = Vector2(setWidth, setWidth / radio);
  }
}
